/*
 * Copyright (c) 2012 Aleksander Zotov, Benedikt Markt, Aliaksei Babkovich
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 *  of this software and associated documentation files (the "Software"),
 *  to deal in the Software without restriction, including without limitation
 *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
 *  and/or sell copies of the Software, and to permit persons to whom the
 *  Software is furnished to do so, subject to the following conditions:
 *  
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 *  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 *  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 *  OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
 *  THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */


package utils;

import java.util.*;

/**
 * This class generates a password with the given symbols
 * 
 * @author Benedikt Markt
 */
public class PasswordGenerator {
	
	private static Random random = new Random();

	/**
	 * Generates a random Password
	 * 
	 * @param length the length of the password
	 * @return a passowrd of th given length
	 */
	public static String generate(int length) {
		String[] alphabets = {
				"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
				"0123456789",
				"_!#$%&()*+-./:;<=>?@" };
		StringBuffer result = new StringBuffer();
		StringBuffer all = new StringBuffer();
		for (int i = 0; i < alphabets.length; i++) {
			if (alphabets[i] == null || alphabets[i].equals("")) {
				throw new IllegalArgumentException("Invalid alphabet: "
						+ alphabets[i]);
			}
			StringBuffer sb = new StringBuffer(alphabets[i]);
			result.append(selectRandom(sb, 1));
			if (result.length() == length) {
				return shuffle(result).toString();
			}
			all.append(sb);
		}
		result.append(selectRandom(all, length - result.length()));
		return shuffle(result).toString();
	}
	
	
	private static StringBuffer selectRandom(StringBuffer alphabet, int n) {
		StringBuffer buffer = new StringBuffer();
		for (int i = 0; i < n; i++) {
			buffer.append(alphabet.charAt(random.nextInt(alphabet.length())));
		}
		return buffer;
	}
	
	/**
	 * mixes the given StringBuffer up randomly
	 * 
	 * @param buffer the StringBuffer to shuffle
	 * @return the shuffled StringBuffer
	 */
	private static StringBuffer shuffle(StringBuffer buffer) {
		for (int i = 0; i < buffer.length(); i++) {
			int i0 = random.nextInt(buffer.length());
			int i1 = random.nextInt(buffer.length());
			char c = buffer.charAt(i0);
			buffer.setCharAt(i0, buffer.charAt(i1));
			buffer.setCharAt(i1, c);
		}
		return buffer;
	}

}